import dayjs from "dayjs"
import router from "@/router"
import { useUserStore } from "@/store/modules/user"
import { useAuthStore } from "@/store/modules/auth"
import { ElMessageBox } from "element-plus"
import request from "@/utils/request"
import { getToken } from "@/utils/storage/cookies"

// 格式化时间
export const formatDateTime = (time: string | number | Date) => {
  if (!time) {
    return "N/A"
  }
  const date = new Date(time)
  return dayjs(date).format("YYYY-MM-DD HH:mm:ss")
}

// 将全局 CSS 变量导入 JS 中使用
export const getCssVariableValue = (cssVariableName: string) => {
  let cssVariableValue = ""
  try {
    // 没有拿到值时，会返回空串
    cssVariableValue = getComputedStyle(document.documentElement).getPropertyValue(cssVariableName)
  } catch (error) {
    console.error(error)
  }
  return cssVariableValue
}

// 重置路由
export function resetRouter() {
  // 注意：所有动态路由路由必须带有 Name 属性，否则可能会不能完全重置干净
  try {
    router.getRoutes().forEach((route) => {
      const { name, meta } = route
      if (name && meta.roles?.length) {
        router.hasRoute(name) && router.removeRoute(name)
      }
    })
  } catch (error) {
    // 强制刷新浏览器也行，只是交互体验不是很好
    window.location.reload()
  }
}

/**
 * 全局权限判断函数，和指令 v-auth 功能类似
 * @param value
 * @returns
 */
export const hasAuth = (value: string[]): boolean => {
  const userStore = useUserStore()
  const authStore = useAuthStore()

  if (userStore.roles.includes('admin')) {
    return true
  }

  if (value.some((key: string) => authStore.auth[key])) {
    return true
  }

  return false
}

interface NestedObject {
  [key: string]: any;
  children?: NestedObject[];
}

// 递归获取树形结构的所有 key
export function getTreeKeys(arr: NestedObject[], key: string): any[] {
  let result: any[] = [];
  arr.forEach(obj => {
    result.push(obj[key]);
    if (obj.children) {
      result = result.concat(getTreeKeys(obj.children, key));
    }
  });
  return result;
}

/**
 * 过滤参数
 * @param { object } originParams
 * @param { object } specialKeys 特殊处理的参数，如：{ date: [startDate, endDate], year: [ startYear, endYear ], more: 'key' }
 * @returns { object } params
 */
export function filterParams(originParams: { [key: string]: any }, specialKeys: { [key: string]: any } = {}): { [key: string]: any } {
  const params: { [key: string]: any } = {};

  for (const key in originParams) {
    if (
      (originParams[key] || originParams[key] === 0) &&
      !specialKeys.hasOwnProperty(key)
    ) {
      params[key] = originParams[key];
    }
  }

  for (const key in specialKeys) {
    // 这个为批量搜索专用，如：小明 小红 小东 => 小明/小红/小东
    if (key == 'more') {
      // 多个用 | 分割
      const moreParamKeys = specialKeys[key].split('|');

      moreParamKeys.forEach((key: string | number) => {
        if (originParams[key]) {
          params[key] = originParams[key].replace(/[\s|\，|\,|\||\；|\;|\{|\}|\@|\#|\$|\&|\*|\(|\)|\[|\]|\_\+\=]+/g, '/');
        }
      });

      continue;
    }
    if (!originParams[key] || !originParams[key].length) continue;
    params[specialKeys[key][0]] = originParams[key][0];
    params[specialKeys[key][1]] = originParams[key][1];
  }

  return params;
}

interface ExportDataOptions {
  url: string;
  params?: object;
  async?: boolean;
}
/**
 * 导出数据
 * @param { object } obj
 * @param { string } obj.url
 * @param { object } obj.params
 * @param { boolean } obj.async 是否异步导出
 * @returns
 * @example
 * exportData({
 *  url: '/api/v1/xxx',
 *  params: {
 *    name: 'xxx',
 *  },
 *  async: true,
 * })
 */
export function exportData(obj: ExportDataOptions): void {
  const params: any = obj.params || {};

  if (obj.async) {
    request({
      url: obj.url,
      params: obj.params,
      method: 'get',
    }).then((res: any) => {
      if (!res.success) return;
      
      ElMessageBox.alert('已经开始导出，当数据量过大时，导出可能需要一些时间，导出进度以及结果可在【右上角的消息通知】中查看', '提示', {
        confirmButtonText: '确定',
      });
    })
  
    return;
  }

  const requestStr = Object.keys(params).reduce<string>((pre, key) => {
    return (pre += `&${key}=${params[key]}`);
  }, "");

  window.open(`${import.meta.env.VITE_BASE_API}${obj.url}?Authorization=${getToken()}${requestStr}`)
}